package mornd.test2;

import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @author: mornd
 * @dateTime: 2023/5/6 - 15:02
 */
public class MyProxy extends Target {
    private MethodInterceptor methodInterceptor;

    private static Method m0;
    private static Method m1;
    private static Method m2;

    private static MethodProxy mp0;
    private static MethodProxy mp1;
    private static MethodProxy mp2;

    public MyProxy(MethodInterceptor methodInterceptor) {
        this.methodInterceptor = methodInterceptor;
    }

    static {
        try {
            m0 = Target.class.getDeclaredMethod("save");
            m1 = Target.class.getDeclaredMethod("save", int.class);
            m2 = Target.class.getDeclaredMethod("save", long.class);

            // () 表示无参，V 表示 void 无返回，I表示int类型参数，J表示long类型参数
            mp0 = MethodProxy.create(Target.class, MyProxy.class, "()V", "save", "saveSuper");
            mp1 = MethodProxy.create(Target.class, MyProxy.class, "(I)V", "save", "saveSuper");
            mp2 = MethodProxy.create(Target.class, MyProxy.class, "(J)V", "save", "saveSuper");
        } catch (Exception e) {
            throw new NoSuchMethodError(e.getMessage());
        }
    }



    // -------------------------- 原始功能的方法
    public void saveSuper() {
        super.save();
    }

    public void saveSuper(int i) {
        super.save(i);
    }

    public void saveSuper(long l) {
        super.save(l);
    }


    // -------------------------- 增强功能的方法
    @Override
    public void save() {
        try {
            methodInterceptor.intercept(this, m0, new Object[]{}, mp0);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    @Override
    public void save(int i) {
        try {
            methodInterceptor.intercept(this, m1, new Object[]{i}, mp1);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    @Override
    public void save(long l) {
        try {
            methodInterceptor.intercept(this, m2, new Object[]{l}, mp2);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}
